package org.liurb.springboot.starter.redis.conf.base;

import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;

import java.time.Duration;

/**
 * 公共Lettuce链接工厂
 *
 * 需子类提供相关配置信息
 *
 * @Author Liurb
 * @Date 2022/11/28
 */
public abstract class BaseLettuceConnectionFactory {

    /**
     * 创建连接池
     *
     * @param database 数据库
     * @return
     */
    public LettuceConnectionFactory getLettuceConnectionFactory(int database) {
        GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();

        //获取redis配置
        RedisConfigProperties redisConfigProperties = getRedisConfigProperties();
        RedisConfigProperties.LettuceConfig.PoolConfig pool = redisConfigProperties.getLettuce().getPool();

        genericObjectPoolConfig.setMaxIdle(pool.getMaxIdle());
        genericObjectPoolConfig.setMinIdle(pool.getMinIdle());
        genericObjectPoolConfig.setMaxTotal(pool.getMaxActive());
        genericObjectPoolConfig.setMaxWait(Duration.ofMillis(pool.getMaxWait()));
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
        redisStandaloneConfiguration.setDatabase(database);
        redisStandaloneConfiguration.setHostName(redisConfigProperties.getHost());
        redisStandaloneConfiguration.setPort(redisConfigProperties.getPort());
        redisStandaloneConfiguration.setPassword(RedisPassword.of(redisConfigProperties.getPassword()));
        LettuceClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder()
                .poolConfig(genericObjectPoolConfig)
                .build();

        LettuceConnectionFactory factory = new LettuceConnectionFactory(redisStandaloneConfiguration, clientConfig);
        // 重新初始化工厂
        factory.afterPropertiesSet();
        return factory;
    }

    /**
     * 获取redis配置的抽象方法
     *
     * 由子类提供该redis配置
     *
     * @return
     */
    public abstract RedisConfigProperties getRedisConfigProperties();
}
